home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1994 April / Inside Multimedia CD-ROM (April 1994).iso / prg / gs / gssource.exe / GDEVXINI.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-24  |  17.8 KB  |  532 lines

  1. /* Copyright (C) 1989, 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gdevxini.c */
  21. /* X Windows driver initialization for Ghostscript library */
  22. #include "gx.h"            /* for gx_bitmap; includes std.h */
  23. #include "memory_.h"
  24. #include "x_.h"
  25. #include "gxdevice.h"
  26. #include "gdevx.h"
  27.  
  28. extern char *getenv(P1(const char *));
  29. extern double atof(P1(const char *));
  30.  
  31. /* Define whether to use a backing pixmap to handle expose events. */
  32. /* Note that this is a variable rather than a #define. */
  33. /* Note also that it is consulted each time we open an X device. */
  34. private int use_backing = 1;
  35.  
  36. /* Define default window parameters. */
  37. /* Some of these can be set in the makefile. */
  38.  
  39. #ifndef PROGRAM_NAME
  40. #  define PROGRAM_NAME "Ghostscript"
  41. #endif
  42.  
  43. #define ARG_BORDER_WIDTH "borderWidth"
  44. #define DEFAULT_BORDER_WIDTH 1
  45.  
  46. #define ARG_BORDER_COLOR "borderColor"
  47. #define DEFAULT_BORDER_COLOR  pixel_black
  48.  
  49. #define ARG_GEOMETRY "geometry"
  50.  
  51. #define DEFAULT_X_POSITION 0
  52. #define DEFAULT_Y_POSITION 0
  53.  
  54. #define ARG_X_RESOLUTION "xResolution"
  55. #define ARG_Y_RESOLUTION "yResolution"
  56.  
  57. /* Define constants for orientation from ghostview */
  58. /* Number represents clockwise rotation of the paper in degrees */
  59. typedef enum {
  60.   Portrait = 0,        /* Normal portrait orientation */
  61.   Landscape = 90,    /* Normal landscape orientation */
  62.   Upsidedown = 180,    /* Don't think this will be used much */
  63.   Seascape = 270    /* Landscape rotated the wrong way */
  64. } orientation;
  65.  
  66. /* Open the X device */
  67. int
  68. gdev_x_open(register gx_device_X *xdev)
  69. {       XSizeHints sizehints;
  70.     int border_width;
  71.     char *border_width_str, *border_color_str;
  72.     unsigned long border_color;
  73.     char *geometry;
  74.     char *window_id;
  75.     XColor screen_color, exact_color;
  76.     XSetWindowAttributes xswa;
  77.     XEvent event;
  78.     XVisualInfo xvinfo;
  79.     int nitems;
  80. #if HaveStdCMap
  81.         XStandardColormap *scmap, *sp;
  82.         Atom prop;
  83. #endif
  84. #ifdef DEBUG
  85. if ( gs_debug['X'] )
  86.     { extern int _Xdebug;
  87.       _Xdebug = 1;
  88.     }
  89. #endif
  90.     if ( !(xdev->dpy = XOpenDisplay((char *)NULL)) )
  91.       { char *dispname = getenv("DISPLAY");
  92.         eprintf1("gs: Cannot open X display `%s'.\n",
  93.              (dispname == NULL ? "(null)" : dispname));
  94.         exit(1);
  95.       }
  96.     if ( (window_id = getenv("GHOSTVIEW")) )
  97.       { if ( !(xdev->ghostview = sscanf(window_id, "%d %d",
  98.                         &(xdev->win), &(xdev->dest))) )
  99.           { eprintf("gs: Cannot get Window from ghostview.\n");
  100.             exit(1);
  101.           }
  102.       }
  103.     if ( xdev->ghostview )
  104.       { XWindowAttributes attrib;
  105.         Atom type;
  106.         int format;
  107.         unsigned long nitems, bytes_after;
  108.         char *buf;
  109.         Atom ghostview_atom = XInternAtom(xdev->dpy, "GHOSTVIEW", False);
  110.         if ( XGetWindowAttributes(xdev->dpy, xdev->win, &attrib) )
  111.           { xdev->scr = attrib.screen;
  112.             xvinfo.visual = attrib.visual;
  113.         xdev->cmap = attrib.colormap;
  114.             xdev->width = attrib.width;
  115.         xdev->height = attrib.height;
  116.           }
  117.         /* Delete property if explicit dest is given */
  118.         if ( XGetWindowProperty(xdev->dpy, xdev->win, ghostview_atom, 0, 
  119.                     256, (xdev->dest != 0), XA_STRING,
  120.                     &type, &format, &nitems, &bytes_after,
  121.                     (unsigned char **)&buf) == 0 )
  122.           { int llx, lly, urx, ury;
  123.         int left_margin = 0, bottom_margin = 0;
  124.         int right_margin = 0, top_margin = 0;
  125.         /* We declare page_orientation as an int so that we can */
  126.         /* use an int * to reference it for sscanf; compilers */
  127.         /* might be tempted to use less space to hold it if */
  128.         /* it were declared as an orientation. */
  129.         int /*orientation*/ page_orientation;
  130.         float xppp, yppp;    /* pixels per point */
  131.         nitems = sscanf(buf,
  132.                 "%d %d %d %d %d %d %f %f %d %d %d %d %d %d",
  133.                         &(xdev->bpixmap), &page_orientation,
  134.                         &llx, &lly, &urx, &ury,
  135.                         &(xdev->x_pixels_per_inch),
  136.                 &(xdev->y_pixels_per_inch),
  137.                 &left_margin, &bottom_margin,
  138.                 &right_margin, &top_margin,
  139.                 &(xdev->width), &(xdev->height));
  140.         if ( (!xdev->dest && !(nitems == 8 || nitems == 12)) ||
  141.              (xdev->dest && nitems != 14) )
  142.           { eprintf("gs: Cannot get ghostview property.\n");
  143.             exit(1);
  144.           }
  145.         if ( xdev->dest && xdev->bpixmap )
  146.           { eprintf("gs: Both destination and backing pixmap specified.\n");
  147.             exit(1);
  148.           }
  149.         xppp = xdev->x_pixels_per_inch / 72.0;
  150.         yppp = xdev->y_pixels_per_inch / 72.0;
  151.         switch (page_orientation)
  152.           {
  153.           case Portrait:
  154.             xdev->initial_matrix.xx = xppp;
  155.             xdev->initial_matrix.xy = 0.0;
  156.             xdev->initial_matrix.yx = 0.0;
  157.             xdev->initial_matrix.yy = -yppp;
  158.             xdev->initial_matrix.tx = -llx * xppp;
  159.             xdev->initial_matrix.ty = ury * yppp;
  160.             break;
  161.           case Landscape:
  162.             xdev->initial_matrix.xx = 0.0;
  163.             xdev->initial_matrix.xy = yppp;
  164.             xdev->initial_matrix.yx = xppp;
  165.             xdev->initial_matrix.yy = 0.0;
  166.             xdev->initial_matrix.tx = -lly * xppp;
  167.             xdev->initial_matrix.ty = -llx * yppp;
  168.             break;
  169.           case Upsidedown:
  170.             xdev->initial_matrix.xx = -xppp;
  171.             xdev->initial_matrix.xy = 0.0;
  172.             xdev->initial_matrix.yx = 0.0;
  173.             xdev->initial_matrix.yy = yppp;
  174.             xdev->initial_matrix.tx = urx * xppp;
  175.             xdev->initial_matrix.ty = -lly * yppp;
  176.             break;
  177.           case Seascape:
  178.             xdev->initial_matrix.xx = 0.0;
  179.             xdev->initial_matrix.xy = -yppp;
  180.             xdev->initial_matrix.yx = -xppp;
  181.             xdev->initial_matrix.yy = 0.0;
  182.             xdev->initial_matrix.tx = ury * xppp;
  183.             xdev->initial_matrix.ty = urx * yppp;
  184.             break;
  185.         }
  186.  
  187.         /* The following sets the imageable area according to the */
  188.         /* bounding box and margins sent by ghostview.            */
  189.         xdev->l_margin = (llx - left_margin) / 72.0;
  190.         xdev->b_margin = (lly - bottom_margin) / 72.0;
  191.         xdev->r_margin = xdev->width / xdev->x_pixels_per_inch -
  192.                  (urx + right_margin) / 72.0;
  193.         xdev->t_margin = xdev->height / xdev->y_pixels_per_inch -
  194.                  (ury + top_margin) / 72.0;
  195.           }
  196.         else
  197.           { eprintf("gs: Cannot get ghostview property.\n");
  198.         exit(1);
  199.           }
  200.       }
  201.     else
  202.       { Screen *scr = DefaultScreenOfDisplay(xdev->dpy);
  203.         xdev->scr = scr;
  204.         xvinfo.visual = DefaultVisualOfScreen(scr);
  205.         xdev->cmap = DefaultColormapOfScreen(scr);
  206.       }
  207.  
  208.     xvinfo.visualid = XVisualIDFromVisual(xvinfo.visual);
  209.     xdev->vinfo = XGetVisualInfo(xdev->dpy, VisualIDMask, &xvinfo, &nitems);
  210.     if ( xdev->vinfo == NULL )
  211.       { eprintf("gs: Cannot get XVisualInfo.\n");
  212.         exit(1);
  213.       }
  214.     xdev->color_info.num_components =
  215.       ((xdev->vinfo->class != StaticGray) &&
  216.        (xdev->vinfo->class != GrayScale) ? 3 : 1);
  217.  
  218. #if HaveStdCMap
  219.     if ( gx_device_has_color(xdev) )
  220.       { if ( xvinfo.visual == DefaultVisualOfScreen(xdev->scr) )
  221.           prop = XA_RGB_DEFAULT_MAP;
  222.         else
  223.           prop = XA_RGB_BEST_MAP;
  224.       }
  225.     else
  226.       prop = XA_RGB_GRAY_MAP;
  227.  
  228.     if ( XGetRGBColormaps(xdev->dpy, RootWindowOfScreen(xdev->scr),
  229.                   &scmap, &nitems, prop) )
  230.       { int i;
  231.         for (i = 0, sp = scmap; i < nitems; i++, sp++)
  232.           { if ( (xdev->ghostview && (xdev->cmap == sp->colormap)) ||
  233.              (!xdev->ghostview && (xdev->vinfo->visualid ==
  234.                         sp->visualid)) )
  235.           { xdev->std_cmap = sp;
  236.             break;
  237.           }
  238.           }
  239.       }
  240.  
  241.     if ( xdev->std_cmap )
  242.       { xdev->cmap = xdev->std_cmap->colormap;
  243.         /* Acquire white and black pixel values. */
  244.         if ( xdev->cmap == DefaultColormapOfScreen(xdev->scr) )
  245.          { pixel_black = BlackPixelOfScreen(xdev->scr);
  246.            pixel_white = WhitePixelOfScreen(xdev->scr);
  247.          }
  248.         else
  249.          {
  250. #define pixv(v)\
  251.   color_index_to_pixel((*xdev->procs->map_rgb_color)((gx_device *)xdev,\
  252.                               v, v, v))
  253.            pixel_black = pixv(0);
  254.            pixel_white = pixv(gx_max_color_value);
  255. #undef pixv
  256.          }
  257.         if ( gx_device_has_color(xdev) )
  258.           { /* Set the color_info in the device structure. */
  259.         xdev->color_info.max_gray =
  260.           xdev->color_info.max_rgb =
  261.             min(xdev->std_cmap->red_max,
  262.             min(xdev->std_cmap->green_max,
  263.                 xdev->std_cmap->blue_max));
  264.         xdev->color_info.depth = 8;    /* arbitrary */
  265.         xdev->color_info.dither_gray =
  266.           xdev->color_info.dither_rgb =
  267.             xdev->color_info.max_rgb + 1;
  268.           }
  269.         else
  270.           { xdev->color_info.max_gray = xdev->std_cmap->red_max +
  271.           xdev->std_cmap->green_max + xdev->std_cmap->blue_max;
  272.         xdev->color_info.depth = 8;    /* arbitrary */
  273.         xdev->color_info.dither_gray = xdev->color_info.max_gray + 1;
  274.           }
  275.       }
  276.     else
  277. #endif
  278.       { if ( xdev->cmap == DefaultColormapOfScreen(xdev->scr) )
  279.           { pixel_black = BlackPixelOfScreen(xdev->scr);
  280.         pixel_white = WhitePixelOfScreen(xdev->scr);
  281.           }
  282.         else
  283.           { XColor xc;
  284.         xc.red = xc.green = xc.blue = 0;
  285.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  286.         pixel_black = xc.pixel;
  287.         xc.red = xc.green = xc.blue = ~(ushort)0;
  288.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  289.         pixel_white = xc.pixel;
  290.           }
  291.  
  292.         /* Figure out monochrome vs. color */
  293.         if ( gx_device_has_color(xdev) )
  294.           /* Just do primary colors for now */
  295.           { XColor xc;
  296.         int i;
  297.         for ( i = 1; i < 7; i++ )
  298.           { xc.red = (i & 4 ? ~(ushort)0 : 0);
  299.             xc.green = (i & 2 ? ~(ushort)0 : 0);
  300.             xc.blue = (i & 1 ? ~(ushort)0 : 0);
  301.             XAllocColor(xdev->dpy, xdev->cmap, &xc);
  302.             xdev->colors[i] = xc.pixel;
  303.           }
  304.         xdev->color_info.max_rgb = 1;
  305.         xdev->color_info.dither_rgb = 2;
  306.         xdev->color_info.depth = 8;
  307.           }
  308.         else
  309.           { int i;
  310.             for ( i = 1; i < 7; i++ )
  311.           xdev->colors[i] = pixel_white;
  312.           }
  313.       }
  314.  
  315.     /* Check for a pixel value equal to gx_no_color_index. */
  316.     if (
  317. #if HaveStdCMap
  318.         !xdev->std_cmap &&
  319. #endif
  320.         (pixel_black == gx_no_color_index ||
  321.          pixel_white == gx_no_color_index)
  322.         )
  323.       { /* Pick a non-zero value guaranteed not to map any primary */
  324.         /* color to gx_no_color_index. */
  325.         xdev->pixel_fix = 0x100000ff ^
  326.           (xdev->colors[1] & 2) ^ (xdev->colors[2] & 4) ^
  327.           (xdev->colors[3] & 8) ^ (xdev->colors[4] & 16) ^
  328.           (xdev->colors[5] & 32) ^ (xdev->colors[6] & 64);
  329.       }
  330.     else
  331.       { xdev->pixel_fix = 0;
  332.       }
  333.  
  334.     if ( !xdev->ghostview )
  335.       { /*
  336.          * Figure out the resolution of our screen; 25.4 is the
  337.          * number of millimeters in an inch.  The only reason for
  338.          * allowing the user to specify the resolution is that
  339.          * X servers commonly lie about it (and about the screen size).
  340.          * We assume that the server is more likely to lie about
  341.          * the resolution than about the pixel size of the screen.
  342.          * Don't do any of this if the resolution was set from the
  343.          * command line (detected by resolution != FAKE_RES).
  344.          */
  345.  
  346.         if ( xdev->x_pixels_per_inch == FAKE_RES )
  347.           { char *x_res_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  348.                           ARG_X_RESOLUTION);
  349.         char *y_res_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  350.                           ARG_Y_RESOLUTION);
  351.         float x_res, y_res;
  352.         if ( x_res_str != NULL && y_res_str != NULL )
  353.           { x_res = atof(x_res_str);
  354.             y_res = atof(y_res_str);
  355.           }
  356.         else
  357.           { int screen_width = WidthOfScreen(xdev->scr);
  358.             int screen_height = HeightOfScreen(xdev->scr);
  359.             x_res = 25.4 * screen_width / WidthMMOfScreen(xdev->scr);
  360.             y_res = 25.4 * screen_height / HeightMMOfScreen(xdev->scr);
  361.             if ( x_res * DEFAULT_WIDTH_INCHES > screen_width ||
  362.             y_res * DEFAULT_HEIGHT_INCHES > screen_height
  363.             )
  364.               { /* Force a full page to fit on the screen */
  365.             /* by adjusting the server's claimed resolution. */
  366.             x_res = (screen_width - 32) / (float)DEFAULT_WIDTH_INCHES;
  367.             y_res = (screen_height - 32) / (float)DEFAULT_HEIGHT_INCHES;
  368.             x_res = y_res = min(x_res, y_res);
  369.               }
  370.           }
  371.         xdev->x_pixels_per_inch = x_res;
  372.         xdev->y_pixels_per_inch = y_res;
  373.           }
  374.  
  375.         /* Get defaults from the database. */
  376.         border_width_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  377.                        ARG_BORDER_WIDTH);
  378.  
  379.         border_width = (border_width_str == NULL ? DEFAULT_BORDER_WIDTH :
  380.                 atoi(border_width_str));
  381.  
  382.         border_color_str = XGetDefault(xdev->dpy, PROGRAM_NAME,
  383.                        ARG_BORDER_COLOR);
  384.  
  385.         border_color = (border_color_str == NULL ||
  386.                  !XAllocNamedColor(xdev->dpy, xdev->cmap, 
  387.                            border_color_str, 
  388.                            &screen_color, &exact_color) ?
  389.                 DEFAULT_BORDER_COLOR :
  390.                 screen_color.pixel);
  391.  
  392.         sizehints.x = DEFAULT_X_POSITION;
  393.         sizehints.y = DEFAULT_Y_POSITION;
  394.         sizehints.width =
  395.                   (int)(xdev->x_pixels_per_inch * DEFAULT_WIDTH_INCHES);
  396.         sizehints.height =
  397.                   (int)(xdev->y_pixels_per_inch * DEFAULT_HEIGHT_INCHES);
  398.         sizehints.flags = 0;
  399.  
  400.         geometry = XGetDefault(xdev->dpy, PROGRAM_NAME, ARG_GEOMETRY);
  401.  
  402.         if (geometry != NULL)
  403.            {    /*
  404.              * Note that border_width must be set first.  We can't use
  405.              * scr, because that is a Screen*, and XGeometry wants
  406.              * the screen number.
  407.              */
  408.             char gstr[40];
  409.             int bitmask;
  410.             sprintf(gstr, "%dx%d+%d+%d", sizehints.width,
  411.                 sizehints.height, sizehints.x, sizehints.y);
  412.             bitmask = XGeometry(xdev->dpy, DefaultScreen(xdev->dpy),
  413.                     geometry, gstr, border_width,
  414.                     1, 1, /* ``Font'' width and height. */
  415.                     0, 0, /* Interior padding. */
  416.                     &sizehints.x, &sizehints.y,
  417.                     &sizehints.width, &sizehints.height);
  418.  
  419.             if (bitmask & (XValue | YValue))
  420.                 sizehints.flags |= USPosition;
  421.  
  422.             if (bitmask & (WidthValue | HeightValue))
  423.                 sizehints.flags |= USSize;
  424.            }
  425.  
  426.         if ( xdev->width == (int)(FAKE_RES*DEFAULT_WIDTH_INCHES) )
  427.           xdev->width = sizehints.width,
  428.           xdev->height = sizehints.height;
  429.         else            /* set from command line */
  430.           sizehints.width = xdev->width,
  431.           sizehints.height = xdev->height;
  432.  
  433.         gx_default_get_initial_matrix((gx_device *)xdev,
  434.                       &(xdev->initial_matrix));
  435.  
  436.         xswa.event_mask = ExposureMask;
  437.         xswa.background_pixel = pixel_black;
  438.         xswa.border_pixel = border_color;
  439.         xswa.colormap = xdev->cmap;
  440.         xdev->win = XCreateWindow(xdev->dpy, RootWindowOfScreen(xdev->scr),
  441.                       sizehints.x, sizehints.y, /* upper left */
  442.                       sizehints.width, sizehints.height,
  443.                       border_width,
  444.                       xdev->vinfo->depth,
  445.                       InputOutput, /* class */
  446.                       xdev->vinfo->visual, /* visual */
  447.                       CWEventMask | CWBackPixel |
  448.                       CWBorderPixel | CWColormap,
  449.                       &xswa);
  450.         XChangeProperty(xdev->dpy, xdev->win, XA_WM_NAME, XA_STRING, 8,
  451.                 PropModeReplace, (const unsigned char *)PROGRAM_NAME,
  452.                 strlen(PROGRAM_NAME));
  453.         XSetNormalHints(xdev->dpy, xdev->win, &sizehints);
  454.        
  455.         if ( use_backing )
  456.           xdev->bpixmap =
  457.             XCreatePixmap(xdev->dpy, xdev->win,
  458.                   xdev->width, xdev->height,
  459.                   xdev->vinfo->depth);
  460.         else
  461.           xdev->bpixmap = (Pixmap)0;
  462.     }
  463.  
  464.     xdev->ht.pixmap = (Pixmap)0;
  465.     xdev->ht.id = gx_no_bitmap_id;;
  466.     xdev->fill_style = FillSolid;
  467.     xdev->function = GXcopy;
  468.  
  469.     /* Set up a graphics context */
  470.     xdev->gc = XCreateGC(xdev->dpy, xdev->win, 0, (XGCValues *)NULL);
  471.     XSetFunction(xdev->dpy, xdev->gc, GXcopy);
  472.     XSetLineAttributes(xdev->dpy, xdev->gc, 0,
  473.                LineSolid, CapButt, JoinMiter);
  474.  
  475.     /* Clear the destination pixmap to avoid initializing with garbage. */
  476.     if ( xdev->dest != (Pixmap)0 )
  477.       { XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  478.         XFillRectangle(xdev->dpy, xdev->dest, xdev->gc,
  479.                0, 0, xdev->width, xdev->height);
  480.       }
  481.     else
  482.       { xdev->dest = (xdev->bpixmap != (Pixmap)0 ?
  483.               xdev->bpixmap : (Pixmap)xdev->win);
  484.       }
  485.  
  486.     /* Clear the background pixmap to avoid initializing with garbage. */
  487.     if ( xdev->bpixmap != (Pixmap)0 )
  488.       { if ( !xdev->ghostview )
  489.           XSetWindowBackgroundPixmap(xdev->dpy, xdev->win, xdev->bpixmap);
  490.         XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  491.         XFillRectangle(xdev->dpy, xdev->bpixmap, xdev->gc,
  492.                0, 0, xdev->width, xdev->height);
  493.       }
  494.  
  495.     /* Initialize foreground and background colors */
  496.     xdev->back_color = pixel_white;
  497.     XSetBackground(xdev->dpy, xdev->gc, pixel_white);
  498.     xdev->fore_color = pixel_white;
  499.     XSetForeground(xdev->dpy, xdev->gc, pixel_white);
  500.     xdev->colors_or = xdev->colors_and = pixel_white;
  501.  
  502.     if ( !xdev->ghostview )
  503.       { /* Make the window appear. */
  504.         XMapWindow(xdev->dpy, xdev->win);
  505.  
  506.         /* Before anything else, do a flush and wait for */
  507.         /* an exposure event. */
  508.         XFlush(xdev->dpy);
  509.         XNextEvent(xdev->dpy, &event);
  510.       }
  511.     else
  512.       { /* Create an unmapped window, that the window manager will ignore.
  513.          * This invisble window will be used to receive "next page"
  514.          * events from ghostview */
  515.         XSetWindowAttributes attributes;
  516.         attributes.override_redirect = True;
  517.         xdev->mwin = XCreateWindow(xdev->dpy, RootWindowOfScreen(xdev->scr),
  518.                        0, 0, 1, 1, 0, CopyFromParent,
  519.                        CopyFromParent, CopyFromParent,
  520.                        CWOverrideRedirect, &attributes);
  521.         xdev->next = XInternAtom(xdev->dpy, "NEXT", False);
  522.         xdev->page = XInternAtom(xdev->dpy, "PAGE", False);
  523.         xdev->done = XInternAtom(xdev->dpy, "DONE", False);
  524.       }
  525.  
  526.     xdev->ht.no_pixmap = XCreatePixmap(xdev->dpy, xdev->win, 1, 1,
  527.                        xdev->vinfo->depth);
  528.  
  529.     XSync(xdev->dpy, 0);
  530.     return 0;
  531. }
  532.